//
//  CCCommandQueue.m
//  CCBluetooth
//
//  Created by zjh on 2021/8/31.
//

#import "CCCommandQueue.h"
@interface CCCommandQueue()
@property (nonatomic, strong) NSMutableArray <CCCommand *>*commands;
@property (nonatomic, strong) NSThread *thread;
@property (nonatomic, strong) dispatch_semaphore_t lock;
@property (nonatomic, assign) CGFloat interval;
@end

static CGFloat __interval = 0;

@implementation CCCommandQueue

+ (void)interval:(CGFloat)interval {
    __interval = interval;
}

- (id)init {
    if (self = [super init]) {
        self.commands = [[NSMutableArray alloc] init];
        self.interval = 0.02;
        self.lock = dispatch_semaphore_create(1);
    }
    return self;
}

- (CGFloat)interval {
    if (__interval > 0.02) {
        return __interval;
    }else{
        return _interval;
    }
}

- (CCCommand *)next {
    CCCommand *command;
    if (self.commands.count!=0) {
        command = self.commands.firstObject;
        dispatch_semaphore_wait(self.lock, DISPATCH_TIME_FOREVER);
        [self.commands removeObject:command];
        dispatch_semaphore_signal(self.lock);
    }
    return command;
}

- (void)addCommand:(CCCommand *)command {
    dispatch_semaphore_wait(self.lock, DISPATCH_TIME_FOREVER);
    [self.commands addObject:command];
    dispatch_semaphore_signal(self.lock);
    if (!self.thread || self.thread.isCancelled) {
        NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(sendCommand) object:nil];
        self.thread = thread;
        [thread start];
    }
}

- (void)sendCommand{
    while (YES) {
        if ([NSThread currentThread].isCancelled) {
            [NSThread exit];
        }
        CCCommand *command = [self next];
        if (command) {
            if ([self.delegate respondsToSelector:@selector(commandQueue:)]) {
                [self.delegate commandQueue:command];
            }
        }
        [NSThread sleepForTimeInterval:self.interval];
        if (self.commands.count==0) {
            [self.thread cancel];
            self.thread = nil;
        }
    }
}

@end
